/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package analiseSintatica.Regras.DeclaracoesIniciais;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSemantica.ErroSemantico;
import analiseSemantica.Tipos.TipoSemantico;
import analiseSemantica.Tipos.TiposSemanticos;
import analiseSemantica.estruturadedados.Identificador;
import analiseSintatica.AnalisadorSintatico;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Expressoes.RegraExpressao;
import analiseSintatica.Regras.*;
import analiseSintatica.Regras.Tipos.RegraTipoPrimitivo;
import java.util.LinkedList;

/**
 *
 * @author Dede do Bem
 * 
 * <const> ::= const <tipo_primitivo> identificador "=" <expressao> ";"
 * 
 */
public class RegraConst extends Regra{

    protected static Regra instancia;

    protected String estrutura = "const <tipo_primitivo> identificador '=' <expressao> ';'";


    /**
     * Construtor privado necessario ao singleton
     */
    private RegraConst() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraConst getInstance() {
        if (instancia == null) {
            instancia = new RegraConst();
        }
        return (RegraConst) instancia;
    }

    @Override
    public TiposSemanticos analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {
        
    	listaTokens.removeFirst();
        TipoSemantico tipoprimitivo = RegraTipoPrimitivo.getInstance().analisar(listaTokens).removeTipos();
      	String tipoprim = (String)tipoprimitivo.getTipo();
      	AnalisadorSintatico.escopoatual.put(listaTokens.getFirst().getLexema(), new Identificador(listaTokens.getFirst().getLexema(), tipoprim, true, false));
        
        reconheceToken(listaTokens, "identificador", estrutura);
        reconheceToken(listaTokens, "=", estrutura);
        TiposSemanticos tiposexpressao = RegraExpressao.getInstance().analisar(listaTokens);
        TipoSemantico tipoexpressao = null;
        String tipoexp = null;
        if(tiposexpressao != null){
        	tipoexpressao = tiposexpressao.removeTipos();
        	tipoexp = (String)tipoexpressao.getTipo();
        }

        if((tiposexpressao != null) && (!tipoprim.equals(tipoexp))){
        	AnalisadorSintatico.errosemanticos.add(new ErroSemantico("Tipo de expressao "+tipoexp+" incompativel com tipo da constante "+tipoprim, tipoprimitivo.getLinha()));
        }
        reconheceLexema(listaTokens, "delimitador", ";", estrutura);
        return null;
     }       

    @Override
    protected void setPrimeiro() {
        this.primeiro.add("const");
    }

    

}
